﻿using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Diagnostics;
using CDSBDemandControl.Model;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using CDSBDemandControlServiceAux.Translator;
using CDSBDemandControl.Configuration;
using Microsoft.TeamFoundation.Client;
using CDSBDemandControlServiceAux.Security;
using System.Collections.Generic;

namespace CDSBDemandControlServiceAux
{
    class DiscriminatorDemandServiceAux
    {
        #region Properties

        string LockFilePath;
        string ServerName;
        //WorkItemStore WIStore;

        #endregion

        #region Constructor

        public DiscriminatorDemandServiceAux()
        {
            try
            {
                this.LoadConfigurations();                
            }
            catch (Exception err)
            {
                EventLog.WriteEntry("CDSBDemandControlService", err.StackTrace, EventLogEntryType.Error, 1);
            }
        }

        #endregion

        #region Methods

        private void LoadConfigurations()
        {
            this.LockFilePath = ConfigManager.GetLockFilePath();
            this.ServerName = ConfigManager.GetServerName();
        }

        private WorkItemStore GetWorkItemStore(string serverName, CDSBNetWorkUser netWorkUser)
        {
            CDSBNetworkCredentials Credentials = new CDSBNetworkCredentials(netWorkUser);

            using (TeamFoundationServer tfs = TeamFoundationServerFactory.GetServer((serverName), Credentials))
            {
                return (WorkItemStore)tfs.GetService(typeof(WorkItemStore));
            }
        }

        public List<CDSBDemandControl.Model.ScenarioModel> ListScenariosAndTasks()
        {
            CDSBNetworkCredentials Credentials = new CDSBNetworkCredentials(ConfigManager.GetTFSUserAuthenticate());
            TeamFoundationServer tfs = TeamFoundationServerFactory.GetServer((ServerName), Credentials);
            WorkItemStore WIStore = (WorkItemStore)tfs.GetService(typeof(WorkItemStore));

            WorkItemCollection col;            

            string WiqlQuery = @"SELECT [System.Id]
                                    FROM WorkItems 
                                        WHERE 
                                    [System.WorkItemType] = 'Scenario'  
                                        AND  
                                    (
                                    [System.State] = 'Em Desenvolvimento'  
                                        OR  
                                    [System.State] = 'Aprovado para Desenvolvimento' 
                                    )
                                ORDER BY [System.Id]";

            col = WIStore.Query(WiqlQuery);
            List<ScenarioModel> scenarios = new List<ScenarioModel>();

            string related = string.Empty;

            foreach (WorkItem item in col)
            {
                string relatedInterno = string.Empty;
                foreach (Link lnk in item.Links)
                {
                    if (lnk.BaseType == BaseLinkType.RelatedLink)
                    {
                        if (related != string.Empty)
                            related += " , ";

                        if (relatedInterno != string.Empty)
                            relatedInterno += " , ";

                        related += ((Microsoft.TeamFoundation.WorkItemTracking.Client.RelatedLink)(lnk)).RelatedWorkItemId;
                        relatedInterno += ((Microsoft.TeamFoundation.WorkItemTracking.Client.RelatedLink)(lnk)).RelatedWorkItemId;
                    }                                        
                }
                scenarios.Add(XMLModelTranslateAux.TranslateScenario(item, relatedInterno));
            }

            WiqlQuery = @"SELECT [System.Id]
                            FROM WorkItems 
                                WHERE 
                            [System.Id] IN (" + related + ") AND [System.WorkItemType] = 'TaskDesenv' ORDER BY [System.Id]";

            col = WIStore.Query(WiqlQuery);

            foreach (WorkItem item in col)
            {
                foreach (ScenarioModel s in scenarios)
                {
                    string[] rel = s.Related.Split(',');
                    foreach (string str in rel)
                    {
                        if (!string.IsNullOrEmpty(str))
                        {
                            if (str.Trim() == item.Id.ToString().Trim())
                                XMLModelTranslateAux.AddTaskDesenvToScenario(s, item);
                        }
                    }
                }
            }

            col = null;            
            tfs.Dispose();
            tfs = null;
            WIStore = null;

            return scenarios;
        }

        public void CreateFileofWorkItems(string filePath, List<ScenarioModel> workItems)
        {
            MemoryStream memoryStream = new MemoryStream();
            BinaryFormatter BFDemand = new BinaryFormatter();
            FileStream FSDemand;

            byte[] buffer;

            BFDemand.Serialize(memoryStream, workItems);

            memoryStream.Flush();

            buffer = memoryStream.GetBuffer();

            memoryStream.Close();
            memoryStream.Dispose();

            LockFile();

            try
            {
                FSDemand = File.Create(filePath);
                FSDemand.Write(buffer, 0, buffer.Length);
                FSDemand.Flush();
                FSDemand.Close();
                FSDemand.Dispose();
            }
            catch (Exception err)
            {
                EventLog.WriteEntry("CDSBDemandControlService", err.StackTrace, EventLogEntryType.Error, 1);
            }
            finally
            {
                UnLockFile();
            }

            buffer = null;
            BFDemand = null;
        }

        private void LockFile()
        {
            FileStream FSDemand = File.Create(LockFilePath);
            FSDemand.WriteByte(66);
            FSDemand.Flush();
            FSDemand.Close();
            FSDemand.Dispose();
        }

        private void UnLockFile()
        {
            FileStream FSDemand = File.Create(LockFilePath);
            FSDemand.WriteByte(65);
            FSDemand.Flush();
            FSDemand.Close();
            FSDemand.Dispose();
        }

        //public WorkItemCollection ExecuteQuery(string wiql)
        //{
        //    return WIStore.Query(wiql);
        //}

        #endregion
    }
}
